function interpret(code) {
    var grid = code.split('\n').map(v => v.split(''));
    var i = 0;//row index of current code
    var j = 0;//column index of current code
    var stack = [];//for store values
    var moves = { '>': [0, 1], '<': [0, -1], 'v': [1, 0], '^': [-1, 0] };
    function move(d) {
        var [ROWS, COLUMNS] = [grid.length, grid[i].length];
        i += moves[d][0];
        j += moves[d][1];
        //wrap screen
        j = j === -1 ? COLUMNS - 1 : j === COLUMNS ? 0 : j;
        i = i === -1 ? ROWS - 1 : i === ROWS ? 0 : i;
    }
    function arithmetic(operator) {
        var [a, b] = [+stack.pop() || 0, +stack.pop() || 0];
        var fn = { '+': () => a + b, '-': () => b - a, '*': () => a * b, '\\': () => a ? Math.floor(b / a) : 0, '%': () => a ? b % a : 0 };
        stack.push(fn[operator]());
    }
    var cmds = {
        '!': () => stack.push((stack.length && stack.pop()) ? 0 : 1),
        '`': () => { var [a, b] = [stack.pop() || 0, stack.pop() || 0]; stack.push(b > a ? 1 : 0); },
        ':': () => stack.push(stack[stack.length - 1] || 0),
        '\\': () => stack.push(stack.pop() || 0, stack.pop() || 0),
        '$': () => stack.pop(),
        '.': () => result += (stack.pop() || 0).toString(),
        ',': () => result += String.fromCharCode(stack.pop() || 0),
        '#': () => move(d),
        'p': () => {
            var [y, x, v] = [stack.pop() || 0, stack.pop() || 0, stack.pop() || 0];
            try { grid[y][x] = String.fromCharCode(v); } catch (error) { console.log(error) }
        },
        'g': () => stack.push(grid[stack.pop()][stack.pop()].charCodeAt(0)),
        '"': () => is_string_mode = true,
        '_': () => d = stack.pop() ? '<' : '>',
        '|': () => d = stack.pop() ? '^' : 'v',
        '?': () => d = '<>^v'[4 * Math.random() | 0]
    }
    var d = '>';
    var result = '';
    var is_string_mode = false;
    while ((cmd = grid[i][j]) != '@') {
        if (is_string_mode) cmd === '"' ? is_string_mode = false : stack.push(cmd.charCodeAt(0)); else {
            if (/[<>\^v]/.test(cmd)) d = cmd;
            else if (/\d/.test(cmd)) stack.push(+cmd);
            else if (/[+\-*/%]/.test(cmd)) arithmetic(cmd);
            else cmd.trim() ? cmds[cmd]() : 'funny?';
        }
        move(d);
    }
    return result;
}

interpret('>987v>.v\nv456<  :\n>321 ^ _@')
interpret([
    '>25*"!dlroW olleH":v',
    '                v:,_@',
    '                >  ^'].join('\n'))
interpret(['08>:1-:v v *_$.@ ', '  ^    _$>\\:^'].join('\n'))
interpret(['01->1# +# :# 0# g# ,# :# 5# 8# *# 4# +# -# _@'].join(''))
interpret(['2>:3g" "-!v\\  g30          <',
    ' |!`"&":+1_:.:03p>03g+:"&"`|',
    ' @               ^  p3\\" ":<',
    '2 2345678901234567890123456789012345678'].join('\n'))

interpret(['v@.<', ' >1^', '>?<^', ' >2^'].join('\n'))